/**
 *                            License
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS  
 * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). 
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.  
 * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR  
 * COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND  
 * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE  
 * MAY BE CONSIDERED TO BE A CONTRACT,
 * THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED 
 * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
 * 
 */
package lineage.bean;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.atomic.AtomicInteger;

import lineage.database.L1AbstractDatabase;
import lineage.util.PerformanceTimer;
import lineage.util.Util;

/**
 * objId(唯一识别编号)分配管理器的抽象类.
 * 
 * @version 2014年3月24日下午4:33:13
 * @author jrwz
 */
public abstract class L1AbstractIdFactory extends L1AbstractDatabase {
    /** 同步监控. */
    private final Object monitor;
    /** 下一个id. */
    private AtomicInteger nextId;

    protected L1AbstractIdFactory() {
        monitor = new Object();
        getMinId();
        getMsg();
        batch(getSql());
    }

    /**
     * 取得起始编号.
     * 
     * @return 起始编号
     */
    protected abstract int getMinId();

    /**
     * 取得要显示的提示信息.
     * 
     * @return 提示信息(在控制台等设备显示的字符串信息)
     */
    protected abstract String getMsg();

    /**
     * 取得要执行的sql语句.
     * 
     * @return sql语句
     */
    protected abstract String getSql();

    @Override
    protected void fillTable(final ResultSet rs) throws SQLException {
        final PerformanceTimer timer = new PerformanceTimer();
        final StringBuilder sb = new StringBuilder();
        sb.append(getMsg());

        int id = 0;
        while (rs.next()) {
            id = rs.getInt("nextid");
        }

        if (id < getMinId()) {
            id = getMinId();
        }

        nextId = new AtomicInteger(id);

        sb.append("(");
        sb.append(id);
        sb.append(")\t耗时 ");
        sb.append(timer.elapsedTimeMillis());
        sb.append(" 毫秒");
        Util.message(Util.SYSTEM_MESSAGE, sb.toString());
    }

    /**
     * 以原子方式将当前值加 1
     * 
     * @return 以前的值
     */
    public int nextId() {
        synchronized (monitor) {
            return nextId.getAndIncrement();
        }
    }

    /**
     * 取得当前值.
     * 
     * @return 当前值
     */
    public int getId() {
        synchronized (monitor) {
            return nextId.get();
        }
    }
}
